package service

import (
	sqlc "bgs/db/sqlc"
	"bgs/grpc/imp/enums"
	"bgs/service/model"
	"bgs/util"
	"context"
	"encoding/json"
	"fmt"
)

type OrderSkuMap map[string]int32

// UpdateActivitySkuFreezeQuantitySinceOrderCreatedWithLock 订单下单成功后增量更新活动冻结数量
func (s *ActivityServiceImp) UpdateActivitySkuFreezeQuantitySinceOrderCreatedWithLock(ctx context.Context, q *sqlc.Queries, orderPtr *sqlc.Order) (err error) {
	return s.updateActivitySkuOnOrderEventWithLock(ctx, q, enums.OrderCreated, orderPtr)
}

// UpdateActivitySkuFreezeQuantitySinceOrderCancelledWithLock 订单撤销成功后减去更新活动冻结数量
func (s *ActivityServiceImp) UpdateActivitySkuFreezeQuantitySinceOrderCancelledWithLock(ctx context.Context, q *sqlc.Queries, orderPtr *sqlc.Order) (err error) {
	return s.updateActivitySkuOnOrderEventWithLock(ctx, q, enums.OrderCancelled, orderPtr)
}

// UpdateActivitySkuFreezeQuantityDeltaSinceOrderCreated 订单支付成功后增量更新活动冻结数量和已售数量
func (s *ActivityServiceImp) UpdateActivitySkuFreezeQuantityAndAvailableQuantitySinceOrderPayedWithLock(ctx context.Context, q *sqlc.Queries, orderPtr *sqlc.Order) (err error) {
	return s.updateActivitySkuOnOrderEventWithLock(ctx, q, enums.OrderPayed, orderPtr)
}

func (s *ActivityServiceImp) updateActivitySkuOnOrderEventWithLock(ctx context.Context, q *sqlc.Queries, oe enums.EnumOrderEvent, orderPtr *sqlc.Order) (err error) {

	slog := util.NewContextLogger(ctx, s.slog)

	cActivity := s.cacher.FetchActivity(orderPtr.ActivityID)
	if cActivity == nil {
		err = fmt.Errorf("not found activity:%d", orderPtr.ActivityID)
		return
	}

	var activityIDOfSkuManaged int64
	if cActivity.Owner == sqlc.EmActivityOwnerSpokesman {
		activityIDOfSkuManaged = orderPtr.ParentActivityID.Int64
	} else {
		activityIDOfSkuManaged = orderPtr.ActivityID
	}

	orderExtInfo := &model.OrderExtInfo{}
	err = json.Unmarshal(orderPtr.ExtInfo, orderExtInfo)
	if err != nil {
		err = fmt.Errorf("unmarshal ext_info失败:%s", err.Error())
		return
	}

	orderSkuMap := make(OrderSkuMap)

	productSpecKeys := util.MapToString(util.ToGenericSlice(orderExtInfo.Details), func(v interface{}) string {
		val := v.(*model.OrderDetailInExtInfo)
		k := val.ProductSpecKey
		orderSkuMap[k] = val.Quantity
		return k
	})

	activitySkusWithLock, err := q.ListActivitySkusByActivityIDAndProductSpecKeysToLock(ctx, sqlc.ListActivitySkusByActivityIDAndProductSpecKeysToLockParams{
		ActivityID:      activityIDOfSkuManaged,
		ProductSpecKeys: productSpecKeys,
	})

	slog.Infof("1、订单event更新活动冻结数量-锁定的activity_skus(%d)条 ok", len(activitySkusWithLock))

	for _, activitySku := range activitySkusWithLock {
		k := activitySku.ProductSpecKey
		if skuQuantity, ok := orderSkuMap[k]; ok {
			switch oe {
			case enums.OrderCreated:
				err = q.UpdateActivitySkuFreezeQuantity(ctx, sqlc.UpdateActivitySkuFreezeQuantityParams{
					ID:             activitySku.ID,
					FreezeQuantity: activitySku.FreezeQuantity + skuQuantity,
				})
				if err != nil {
					return
				}
			case enums.OrderPayed:
				err = q.UpdateActivitySkuSubtractFreezeQuantityAddSoldedQuantity(ctx, sqlc.UpdateActivitySkuSubtractFreezeQuantityAddSoldedQuantityParams{
					ID:             activitySku.ID,
					FreezeQuantity: activitySku.FreezeQuantity - skuQuantity,
					SoldedQuantity: activitySku.SoldedQuantity + skuQuantity,
				})
				if err != nil {
					return
				}
			case enums.OrderCancelled:
				err = q.UpdateActivitySkuFreezeQuantity(ctx, sqlc.UpdateActivitySkuFreezeQuantityParams{
					ID:             activitySku.ID,
					FreezeQuantity: activitySku.FreezeQuantity - skuQuantity,
				})
				if err != nil {
					return
				}
			default:
				slog.Infof("no switch case for event:%s", oe)
			}
		}
	}

	slog.Infof("2、订单event:%s更新活动sku ok", oe)

	return

}
